/* Copyright (c) 2012, Michael Gruhn
 * All rights reserved.
 * 
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
 * THIS SOFTWARE.
 */

desc:Limiter
slider1:0<-30,0,1>Threshold (dB)
slider2:0<-30,0,1>Ceiling (dB)

@init
/* rc smoothing filters */
C1 = exp(-1/(25/1000*srate));
C2 = exp(-1/(25/1000*srate));
C3 = exp(-1/(5/1000*srate));

len = 10/1000*srate;
bufl = 0;
bufr = len;
pos = 0;

pdc_delay = len;
pdc_bot_ch = 0;
pdc_top_ch = 2;

@slider
thresh = 10^(slider1/20);
make_gain = 10^((-slider1+slider2)/20);
ceiling = 10^(slider2/20);

@sample
in = max(abs(spl0),abs(spl1));

/* smooth via a rc low pass */
out1 = in  >out1 ? in   : in   + C1 * (out1-in);
out2 = out1>out2 ? out1 : out1 + C2 * (out2-out1);
out3 = out2 + C3 * (out3-out2);

out = out3;

bufl[pos] = spl0;
bufr[pos] = spl1;

pos = (pos+1)%len;

gain = (out > thresh ? thresh/out : 1)*make_gain;

spl0 = bufl[pos] * gain;
spl0 = max(min(spl0,ceiling),-ceiling);
spl1 = bufr[pos] * gain;
spl1 = max(min(spl1,ceiling),-ceiling);